package main

import (
	"context"
	"errors"
	"fmt"
	"golang.org/x/sync/errgroup"
	"net/http"
	"os"
	"os/signal"
	"time"
)

func main() {

	errGroup, ctx := errgroup.WithContext(context.Background())

	// 开启http服务8080
	errGroup.Go(func() error {

		server := &http.Server{
			Addr: ":8080",
		}

		// 保证服务停用时，不会造成泄露
		errChan := make(chan error, 1)

		go func() {
			fmt.Println("开启http服务8080")
			err := server.ListenAndServe()
			errChan <- err
		}()

		select {

		case <-ctx.Done():
			expCtx, cancel := context.WithTimeout(context.Background(), 3*time.Minute)
			defer cancel()
			err := server.Shutdown(expCtx)
			fmt.Printf("受其它服务影响关闭http服务8080, %v\n", err)
			return err

		case err := <-errChan:
			return err
		}

	})

	// 开启http服务9090
	errGroup.Go(func() error {

		server := &http.Server{
			Addr: ":9090",
		}

		// 保证服务停用时，不会造成泄露
		errChan := make(chan error, 1)

		go func() {
			fmt.Println("开启http服务9090")
			err := server.ListenAndServe()
			errChan <- err
		}()

		select {

		case <-ctx.Done():
			expCtx, cancel := context.WithTimeout(context.Background(), 3*time.Minute)
			defer cancel()
			err := server.Shutdown(expCtx)
			fmt.Printf("受其它服务影响关闭http服务9090, %v\n", err)
			return err

		case err := <-errChan:
			return err

		}

	})

	// 开启signal监听
	errGroup.Go(func() error {

		signalChan := make(chan os.Signal, 2)
		signal.Notify(signalChan, os.Kill, os.Interrupt)
		defer signal.Stop(signalChan)

		select {

		case <-ctx.Done():
			signal.Stop(signalChan)
			fmt.Println("受影响关闭系统信号")
			return nil

		case sig := <-signalChan:
			signal.Stop(signalChan)
			return errors.New(fmt.Sprintf("由%s触发关闭操作", sig))

		}

	})

	err := errGroup.Wait()

	if err != nil {
		fmt.Println(err)
		return
	}

}
